#ifndef TCPBLOCK_H
#define TCPBLOCK_H

#include <QDataStream>
#include <QtGlobal>
#include <QDebug>

#include "TransferType.h"

/*!
 * @class     : TcpBlock
 * @brief     : Tcp传输的数据块，每次交付给下层套接字都是一个TcpBlock类型
 * @author    : BinWatson
 * @date      : 2022-06-24 11:09:58
 */
struct TcpBlock
{
    qint32 blockSize;       // 一个数据块大小不超过4G
    qint64 magicNumber;     // 用于区分不同数据块组
    TransferType type;      // 区分不同的类型
    QByteArray dataBlock;   // payload

    bool isEmpty() const {
        return dataBlock.isEmpty();
    }

    /**
     * @brief   : 整个TcpBlock的有效数据长度
     * @return  : qint64 有效数据长度
     * @author  : BinWatson
     * @version : v1.0
     * @date    : 2022-06-24 11:08:57
     * @details : 这里的有效数据指的是dataBlock中的有效数据，
     *            包括QByteArray的元数据占用的空间
     */
    qint64 tcpBlockSize() const
    {
        return qint64(sizeof(blockSize)) +
               qint64(sizeof(magicNumber)) +
               qint64(sizeof(type)) +
               dataBlock.size() +
               qint64(sizeof(int)); /* 一个四字节的指针 */
    }

    constexpr qint64 headSize() const
    {
        return  (qint64)sizeof(blockSize) +
                sizeof(magicNumber) +
                sizeof(type);
    }

    qint64 payloadSize() const
    {
        return tcpBlockSize() - headSize();
    }
};

extern QDataStream& operator>>(QDataStream &in, TcpBlock &block);
extern QDataStream& operator<<(QDataStream &out, TcpBlock &block);
extern QDebug operator<<(QDebug debug, const TcpBlock &block);


#endif // TCPBLOCK_H
